Micron Document
🎖️GitЯра🎖️


Displaying Raw • Download

core/model/src/commonMain/kotlin/org/meshtastic/core/model/NodeAddress.kt 4e15ef1c7f68f8c683fe8b7ff741a5167e154d2e (4e15ef1c) Text, 5.62 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.model

Tff7b72import T7ee787org.meshtastic.core.common.util.formatString
Tff7b72import T7ee787kotlin.jvm.JvmInline

T8b949e/**
* Type-safe representation of a mesh node address.
*
* Replaces stringly-typed node addressing (`"^all"`, `"^local"`, `"!hexid"`) with exhaustive sealed dispatch, enabling
* compile-time verification of address handling.
*/
Tff7b72sealed Tff7b72class T56d364NodeAddress Tb4b4b4{
T8b949e/** Broadcast to all nodes in the mesh. */
Tff7b72data Tff7b72object T56d364Broadcast Tb4b4b4: Te6edf3NodeAddressTb4b4b4(Tb4b4b4)

T8b949e/** The local node (used as `from` when the sender's ID is unknown). */
Tff7b72data Tff7b72object T56d364Local Tb4b4b4: Te6edf3NodeAddressTb4b4b4(Tb4b4b4)

T8b949e/** Address by numeric node number (the canonical mesh-level identifier). */
Tff7b72data Tff7b72class T56d364ByNumTb4b4b4(Tff7b72val Te6edf3numTb4b4b4: Tffa657IntTb4b4b4) Tb4b4b4: Te6edf3NodeAddressTb4b4b4(Tb4b4b4)

T8b949e/** Address by hex string ID (e.g. `"!a1b2c3d4"`). */
Tff7b72data Tff7b72class T56d364ByIdTb4b4b4(Tff7b72val Te6edf3idTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4: Te6edf3NodeAddressTb4b4b4(Tb4b4b4)

T8b949e/** Convert back to the legacy string representation used in [DataPacket]. */
Tff7b72fun Td2a8fftoIdStringTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Tff7b72when Tb4b4b4(Tff7b72thisTb4b4b4) Tb4b4b4{
Te6edf3Broadcast Tff7b72-Tff7b72> Te6edf3ID_BROADCAST
Te6edf3Local Tff7b72-Tff7b72> Te6edf3ID_LOCAL
Tff7b72is Te6edf3ByNum Tff7b72-Tff7b72> Te6edf3numToDefaultIdTb4b4b4(Te6edf3numTb4b4b4)
Tff7b72is Te6edf3ById Tff7b72-Tff7b72> Te6edf3id
Tb4b4b4}

T8b949e/** Build a [ContactKey] for this address on the given [channel]. */
Tff7b72fun Td2a8fftoContactKeyTb4b4b4(Te6edf3channelTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3ContactKey Tff7b72= Te6edf3ContactKeyTb4b4b4(Ta5d6ff"Tffd700$Te6edf3channelTffd700${Te6edf3toIdStringTb4b4b4(Tb4b4b4)Tffd700}Ta5d6ff"Tb4b4b4)

Tff7b72companion Tff7b72object Tb4b4b4{
T8b949e/** The broadcast address string `"^all"`. */
Tff7b72const Tff7b72val Te6edf3ID_BROADCAST Tff7b72= Ta5d6ff"Ta5d6ff^allTa5d6ff"

T8b949e/** The local node address string `"^local"`. */
Tff7b72const Tff7b72val Te6edf3ID_LOCAL Tff7b72= Ta5d6ff"Ta5d6ff^localTa5d6ff"

T8b949e/** The broadcast node number (`0xFFFFFFFF`). */
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72const Tff7b72val Te6edf3NODENUM_BROADCAST Tff7b72= Tb4b4b4(T79c0ff0Te6edf3xffffffffTb4b4b4)Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)

T8b949e/** Public-key cryptography (PKC) channel index. */
Tff7b72const Tff7b72val Te6edf3PKC_CHANNEL_INDEX Tff7b72= T79c0ff8

Tff7b72private Tff7b72const Tff7b72val Te6edf3NODE_ID_PREFIX Tff7b72= Ta5d6ff"Ta5d6ff!Ta5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3HEX_RADIX Tff7b72= T79c0ff1T79c0ff6

T8b949e/** Parse a legacy string address into a typed [NodeAddress]. */
Tff7b72fun Td2a8fffromStringTb4b4b4(Te6edf3idTb4b4b4: Tffa657String?Tb4b4b4)Tb4b4b4: Te6edf3NodeAddress Tff7b72= Tff7b72when Tb4b4b4{
Te6edf3id Tff7b72=Tff7b72= Tff7b72null Tff7b72|Tff7b72| Te6edf3id Tff7b72=Tff7b72= Te6edf3ID_BROADCAST Tff7b72-Tff7b72> Te6edf3Broadcast
Te6edf3id Tff7b72=Tff7b72= Te6edf3ID_LOCAL Tff7b72-Tff7b72> Te6edf3Local
Te6edf3idTb4b4b4.Te6edf3startsWithTb4b4b4(Te6edf3NODE_ID_PREFIXTb4b4b4) Tff7b72-Tff7b72> Te6edf3idToNumTb4b4b4(Te6edf3idTb4b4b4)Tff7b72?.Te6edf3letTb4b4b4(Tff7b72::Te6edf3ByNumTb4b4b4) Tff7b72?: Te6edf3ByIdTb4b4b4(Te6edf3idTb4b4b4)
Tff7b72else Tff7b72-Tff7b72> Te6edf3ByIdTb4b4b4(Te6edf3idTb4b4b4)
Tb4b4b4}

T8b949e/** Convert a node number to its canonical hex string ID (e.g. `"!a1b2c3d4"`). */
Tff7b72fun Td2a8ffnumToDefaultIdTb4b4b4(Te6edf3nTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Tffa657String Tff7b72= Te6edf3formatStringTb4b4b4(Ta5d6ff"Ta5d6ff!%08xTa5d6ff"Tb4b4b4, Te6edf3nTb4b4b4)

T8b949e/**
* Parse a hex node ID string (with or without `!` prefix) to its integer value, or null if the input is not a
* valid 32-bit hex value. Values larger than `0xFFFFFFFF` return null rather than silently truncating, so a
* malformed `!100000000` won't be misclassified as node `0`.
*/
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffMagicNumberTa5d6ff"Tb4b4b4)
Tff7b72fun Td2a8ffidToNumTb4b4b4(Te6edf3idTb4b4b4: Tffa657String?Tb4b4b4)Tb4b4b4: Tffa657Int? Tff7b72=
Te6edf3idTff7b72?.Te6edf3removePrefixTb4b4b4(Te6edf3NODE_ID_PREFIXTb4b4b4)Tff7b72?.Te6edf3toLongOrNullTb4b4b4(Te6edf3HEX_RADIXTb4b4b4)Tff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657it Tff7b72in T79c0ff0LTb4b4b4.Tb4b4b4.T79c0ff0Te6edf3xFFFFFFFFL Tb4b4b4}Tff7b72?.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

T8b949e/**
* Type-safe wrapper for contact key strings (channel index + node address).
*
* Contact keys are persisted as strings in the format `"<channel><nodeId>"` (e.g. `"0^all"`, `"1!a1b2c3d4"`).
*/
Tf0883e@JvmInline
Tff7b72value Tff7b72class T56d364ContactKeyTb4b4b4(Tff7b72val Te6edf3valueTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
T8b949e/**
* The channel index if the key carries a leading channel digit, or `null` for a legacy unprefixed direct-message
* key. Callers that must distinguish "channel 0" from "no channel prefix" (e.g. PKI vs legacy DM routing) need this
* rather than [channel].
*/
Tff7b72val Te6edf3channelOrNullTb4b4b4: Tffa657Int?
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3valueTb4b4b4.Te6edf3firstOrNullTb4b4b4(Tb4b4b4)Tff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isDigitTb4b4b4(Tb4b4b4) Tb4b4b4}Tff7b72?.Te6edf3digitToIntTb4b4b4(Tb4b4b4)

T8b949e/** The channel index (first character). Returns 0 if the key is empty or has no channel digit. */
Tff7b72val Te6edf3channelTb4b4b4: Tffa657Int
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3channelOrNull Tff7b72?: T79c0ff0

T8b949e/**
* The node address portion: everything after the channel digit, or the whole key when there is no channel prefix.
* Empty if the key is empty.
*/
Tff7b72val Te6edf3addressStringTb4b4b4: Tffa657String
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Tff7b72if Tb4b4b4(Te6edf3channelOrNull Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Te6edf3valueTb4b4b4.Te6edf3substringTb4b4b4(T79c0ff1Tb4b4b4) Tff7b72else Te6edf3value

T8b949e/** Parsed [NodeAddress] for the contact. */
Tff7b72val Te6edf3addressTb4b4b4: Te6edf3NodeAddress
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3fromStringTb4b4b4(Te6edf3addressStringTb4b4b4)

Tff7b72companion Tff7b72object Tb4b4b4{
T8b949e/** Create a broadcast contact key for the given channel. */
Tff7b72fun Td2a8ffbroadcastTb4b4b4(Te6edf3channelTb4b4b4: Tffa657Int Tff7b72= T79c0ff0Tb4b4b4)Tb4b4b4: Te6edf3ContactKey Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3BroadcastTb4b4b4.Te6edf3toContactKeyTb4b4b4(Te6edf3channelTb4b4b4)
Tb4b4b4}
Tb4b4b4}

T8b949e/** Type-safe interpretation of [DataPacket.to]. */
Tff7b72val Te6edf3DataPacketTb4b4b4.Te6edf3destinationTb4b4b4: Te6edf3NodeAddress
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3fromStringTb4b4b4(Te6edf3toTb4b4b4)

T8b949e/** Type-safe interpretation of [DataPacket.from]. */
Tff7b72val Te6edf3DataPacketTb4b4b4.Te6edf3sourceTb4b4b4: Te6edf3NodeAddress
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3fromStringTb4b4b4(Te6edf3fromTb4b4b4)

T8b949e/** Checks whether this packet originated from the local device. */
Tff7b72fun Te6edf3DataPacketTb4b4b4.Td2a8ffisFromLocalTb4b4b4(Te6edf3myNodeNumTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Tffa657Boolean Tb4b4b4{
Tff7b72val Te6edf3src Tff7b72= Te6edf3source
Tff7b72return Te6edf3src Tff7b72is Te6edf3NodeAddressTb4b4b4.Te6edf3Local Tff7b72|Tff7b72| Tb4b4b4(Te6edf3myNodeNum Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3src Tff7b72is Te6edf3NodeAddressTb4b4b4.Te6edf3ByNum Tff7b72&Tff7b72& Te6edf3srcTb4b4b4.Te6edf3num Tff7b72=Tff7b72= Te6edf3myNodeNumTb4b4b4)
Tb4b4b4}

T8b949e/** Checks whether this packet is addressed to the broadcast channel. */
Tff7b72val Te6edf3DataPacketTb4b4b4.Te6edf3isBroadcastTb4b4b4: Tffa657Boolean
Tff7b72getTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3destination Tff7b72is Te6edf3NodeAddressTb4b4b4.Te6edf3Broadcast

Served by rngit 1.5.0 - Generated in 0.06s